home *** CD-ROM | disk | FTP | other *** search
- /*
- * symbols.c
- *
- * This file is part of the basis of the Forms Library
- *
- * It contains the routine that draws all the symbols like arrows, etc.
- * instead of labels. It can easily be extended with new symbols.
- *
- * Written by Mark Overmars
- *
- * Version 2.1 a
- * Date: Oct 2, 1992
- */
-
- #include <stdio.h>
- #include <string.h>
- #include "gl/gl.h"
- #include "forms.h"
-
- typedef struct {
- char name[15]; /* its name */
- void (*drawit)(int); /* the drawing routine */
- int scalable; /* whether symbol can be scaled */
- int empty; /* whether entry is used already */
- } SYMBOL;
-
- #define MAXSYMBOL 211
- /* Maximal number of symbols in table. Only half of them are
- used. Should be prime. */
-
- static SYMBOL symbols[MAXSYMBOL]; /* The symbols */
- static int symbnumb = -1; /* Their number */
-
- static int h1(char name[])
- /* The first hash function. */
- {
- if (name[0] == '\0') return 0;
- else if (name[1] == '\0') return name[0] % MAXSYMBOL;
- else if (name[2] == '\0') return (31*name[0]+name[1]) % MAXSYMBOL;
- else return (71*name[0]+31*name[1]+name[2]) % MAXSYMBOL;
- }
-
- static int h2(char name[])
- /* The second hash function. */
- {
- if (name[0] == '\0') return 0;
- else if (name[1] == '\0') return (3*name[0]) % MAXSYMBOL;
- else return (51*name[0]+3*name[1]) % MAXSYMBOL;
- }
-
- static int find(char name[])
- /* Returns the index for the name or -1. */
- {
- int pos = h1(name), hh2 = h2(name);
- while (strcmp(symbols[pos].name,name) != 0 && ! symbols[pos].empty)
- pos = (pos + hh2) % MAXSYMBOL;
- if (symbols[pos].empty) return -1; else return pos;
- }
-
- static int find_empty(char name[])
- /* Returns the first empty index for the name (-1 when name exists). */
- {
- int pos = h1(name), hh2 = h2(name);
- while (strcmp(symbols[pos].name,name) != 0 && ! symbols[pos].empty)
- pos = (pos + hh2) % MAXSYMBOL;
- if (symbols[pos].empty) return pos; else return -1;
- }
-
- /**************** The routines seen by the user *************************/
-
- int fl_add_symbol(char name[], FL_DRAWPTR drawit, int scalable)
- /* Adds a symbol to the system. Returns whether correct. */
- {
- int pos;
- pos = find_empty(name);
- if (pos == -1 || symbnumb > MAXSYMBOL / 2)
- {fl_error("fl_add_symbol","Cannot add another symbol."); return FALSE;}
- strcpy(symbols[pos].name,name);
- symbols[pos].drawit = drawit;
- symbols[pos].empty = FALSE;
- symbols[pos].scalable = scalable;
- symbnumb++;
- return TRUE;
- }
-
- int fl_draw_symbol(char label[],float x,float y,float w,float h, int col)
- /* Draws the symbol with the given label, returns whether it exists */
- {
- int pos , i, shift;
- char str[50];
- int rotangle = 0;
- int equalscale = 0;
- if (label[0] != '@') return FALSE;
- if (label[1] == '#') {equalscale = 1; pos = 2;} else pos = 1;
- shift = pos;
- if (label[pos] >= '1' && label[pos] <= '9')
- {
- switch (label[pos])
- {
- case '9': rotangle = 450; break;
- case '8': rotangle = 900; break;
- case '7': rotangle = 1350; break;
- case '4': rotangle = 1800; break;
- case '1': rotangle = 2250; break;
- case '2': rotangle = 2700; break;
- case '3': rotangle = 3150; break;
- }
- shift = pos+1;
- }
- else if (label[pos] == '0')
- {
- rotangle = 1000*(label[pos+1]-'0') + 100*(label[pos+2]-'0') +
- 10*(label[pos+3]-'0');
- shift = pos+4;
- }
- i = 0;
- do str[i] = label[i+shift]; while (str[i++] != NULL);
- pos = find(str);
- if (pos == -1) return FALSE;
- pushmatrix();
- translate(x+w/2.0,y+h/2.0,0.0);
- if (symbols[pos].scalable)
- {
- if (equalscale)
- { if (w<h) scale(0.4*w,0.4*w,1.0); else scale(0.4*h,0.4*h,1.0); }
- else
- scale(0.4*w,0.4*h,1.0);
- rotate(rotangle,'z');
- }
- (symbols[pos].drawit)(col);
- popmatrix();
- return TRUE;
- }
-
- /******************** THE DEFAULT SYMBOLS ****************************/
-
- /* Some help stuff */
-
- #define BP bgnpolygon()
- #define EP endpolygon()
- #define BL bgnline();
- #define EL endline();
- #define BC bgnclosedline();
- #define EC endclosedline();
-
- static void circle(float x,float y,float r,int c)
- { fl_color(c); circf(x,y,r); fl_color(BLACK); circ(x,y,r); }
-
- static void rectangle(float x1,float y1,float x2,float y2,int c)
- { fl_color(c); rectf(x1,y1,x2,y2); fl_color(BLACK); rect(x1,y1,x2,y2); }
-
- static void vv(float x,float y)
- { float v[2] ; v[0] = x; v[1] = y; v2f(v);}
-
- /* The drawing routines */
-
- static void draw_arrow1(int col)
- {
- fl_color(col);
- BP; vv(-0.8,-0.4); vv(-0.8,0.4); vv(0.3,0.4); vv(0.3,-0.4); EP;
- BP; vv(0.0,0.8); vv(0.8,0.0); vv(0.0,-0.8); EP;
- fl_color(BLACK);
- BC; vv(-0.8,-0.4); vv(-0.8,0.4); vv(0.0,0.4); vv(0.0,0.8); vv(0.8,0.0);
- vv(0.0,-0.8); vv(0.0,-0.4); EC;
- }
-
- static void draw_arrow2(int col)
- {
- fl_color(col);
- BP; vv(-0.20,0.7); vv(0.50,0.0); vv(-0.20,-0.7); EP;
- fl_color(BLACK);
- BC; vv(-0.20,0.7); vv(0.50,0.0); vv(-0.20,-0.7); EC;
- }
-
- static void draw_arrow3(int col)
- {
- fl_color(col);
- BP; vv(0.15,0.7); vv(0.85,0.0); vv(0.15,-0.7); EP;
- BP; vv(-0.55,0.7); vv(0.15,0.0); vv(-0.55,-0.7); EP;
- fl_color(BLACK);
- BC; vv(0.15,0.7); vv(0.85,0.0); vv(0.15,-0.7); EC;
- BC; vv(-0.55,0.7); vv(0.15,0.0); vv(-0.55,-0.7); EC;
- }
-
- static void draw_arrow01(int col)
- { rotate(1800,'z'); draw_arrow1(col); }
-
- static void draw_arrow02(int col)
- { rotate(1800,'z'); draw_arrow2(col); }
-
- static void draw_arrow03(int col)
- { rotate(1800,'z'); draw_arrow3(col); }
-
- static void draw_doublearrow(int col)
- {
- fl_color(col);
- BP; vv(-0.35,-0.4); vv(-0.35,0.4); vv(0.35,0.4); vv(0.35,-0.4); EP;
- BP; vv(0.25,0.8); vv(0.85,0.0); vv(0.25,-0.8); EP;
- BP; vv(-0.25,0.8); vv(-0.85,0.0); vv(-0.25,-0.8); EP;
- fl_color(BLACK);
- BC; vv(-0.25,0.4); vv(0.25,0.4); vv(0.25,0.8); vv(0.85,0.0);
- vv(0.25,-0.8); vv(0.25,-0.4); vv(-0.25,-0.4); vv(-0.25,-0.8);
- vv(-0.85,0.0); vv(-0.25,0.8); EC;
- }
-
- static void draw_arrow(int col)
- {
- fl_color(col);
- BP; vv(0.65,0.1); vv(1.0,0.0); vv(0.65,-0.1); EP;
- fl_color(BLACK);
- BL; vv(-1.0,0.0); vv(0.65,0.0); EL;
- BC; vv(0.65,0.1); vv(1.0,0.0); vv(0.65,-0.1); EC;
- }
-
- static void draw_returnarrow(int col)
- {
- fl_color(col);
- BP; vv(-0.8,0.0); vv(-0.1,0.7); vv(-0.1,-0.7); EP;
- fl_color(BLACK);
- BC; vv(-0.8,0.0); vv(-0.1,0.7); vv(-0.1,-0.7); EC;
- BL; vv(-0.1,0.0); vv(0.8,0.0); vv(0.8,0.7); EL;
- }
-
- static void draw_square(int col)
- { rectangle(-0.7,-0.7,0.7,0.7,col); }
-
- static void draw_circle(int col)
- { circle(0.0,0.0,0.7,col); }
-
- static void draw_line(int col)
- { fl_color(col); BL; vv(-1.0,0.0); vv(1.0,0.0); EL; }
-
- static void draw_plus(int col)
- {
- fl_color(col);
- BP; vv(-0.9,-0.15); vv(-0.9,0.15); vv(0.9,0.15); vv(0.9,-0.15); EP;
- BP; vv(-0.15,-0.9); vv(-0.15,0.9); vv(0.15,0.9); vv(0.15,-0.9); EP;
- fl_color(BLACK);
- BC;
- vv(-0.9,-0.15); vv(-0.9,0.15); vv(-0.15,0.15); vv(-0.15,0.9);
- vv(0.15,0.9); vv(0.15,0.15); vv(0.9,0.15); vv(0.9,-0.15);
- vv(0.15,-0.15); vv(0.15,-0.9); vv(-0.15,-0.9); vv(-0.15,-0.15);
- EC;
- }
-
- static void draw_menu(int col)
- {
- fl_color(FL_RIGHT_BOUND_COL);
- rectf(-0.5, -1.0, 0.8, 0.1);
- rectf(-0.5, 0.45, 0.8, 0.85);
- rectangle(-0.65, -0.85, 0.65, 0.25, col);
- rectangle(-0.65, 0.6, 0.65, 1.0, col);
- }
-
- void fl_init_symbols()
- /* initialises all the symbol entries and adds the default symbols */
- {
- int i;
- symbnumb = 0;
- for (i=0; i<MAXSYMBOL; i++) symbols[i].empty = TRUE;
-
- fl_add_symbol("", draw_arrow1, 1);
- fl_add_symbol("->", draw_arrow1, 1);
- fl_add_symbol(">", draw_arrow2, 1);
- fl_add_symbol(">>", draw_arrow3, 1);
- fl_add_symbol("<-", draw_arrow01, 1);
- fl_add_symbol("<", draw_arrow02, 1);
- fl_add_symbol("<<", draw_arrow03, 1);
- fl_add_symbol("<->", draw_doublearrow, 1);
- fl_add_symbol("arrow", draw_arrow, 1);
- fl_add_symbol("returnarrow", draw_returnarrow, 1);
- fl_add_symbol("square", draw_square, 1);
- fl_add_symbol("circle", draw_circle, 1);
- fl_add_symbol("line", draw_line, 1);
- fl_add_symbol("plus", draw_plus, 1);
- fl_add_symbol("menu", draw_menu, 1);
- }
-